using GroupSix.Domain.Repositories;
using GroupSix.Domain.Entity.App;
using GroupSix.Domain.common;
using GroupSix.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace GroupSix.Infrastructure.Reposoitories;

/// <summary>
/// 操作日志仓储实现
/// </summary>
public class OperationLogRepository : EfRepository<GsOperationLog>, IOperationLogRepository
{
    public OperationLogRepository(GroupSixDbContext context) : base(context)
    {
    }

    /// <summary>
    /// 根据操作人获取日志列表
    /// </summary>
    public async Task<PageResult<GsOperationLog>> GetLogsByOperatorAsync(Guid operatorId, int page = 1, int pageSize = 20)
    {
        var queryable = _tb
            .Where(l => l.OperatorId == operatorId)
            .OrderByDescending(l => l.OperationTime);

        var totalCount = await queryable.CountAsync();

        var items = await queryable
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return new PageResult<GsOperationLog>
        {
            Items = items,
            TotalCount = totalCount,
            PageIndex = page,
            PageSize = pageSize
        };
    }

    /// <summary>
    /// 根据操作类型获取日志列表
    /// </summary>
    public async Task<PageResult<GsOperationLog>> GetLogsByOperationTypeAsync(string operationType, int page = 1, int pageSize = 20)
    {
        var queryable = _tb
            .Where(l => l.OperationType == operationType)
            .OrderByDescending(l => l.OperationTime);

        var totalCount = await queryable.CountAsync();

        var items = await queryable
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return new PageResult<GsOperationLog>
        {
            Items = items,
            TotalCount = totalCount,
            PageIndex = page,
            PageSize = pageSize
        };
    }

    /// <summary>
    /// 根据模块获取日志列表
    /// </summary>
    public async Task<PageResult<GsOperationLog>> GetLogsByModuleAsync(string module, int page = 1, int pageSize = 20)
    {
        var queryable = _tb
            .Where(l => l.Module == module)
            .OrderByDescending(l => l.OperationTime);

        var totalCount = await queryable.CountAsync();

        var items = await queryable
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return new PageResult<GsOperationLog>
        {
            Items = items,
            TotalCount = totalCount,
            PageIndex = page,
            PageSize = pageSize
        };
    }

    /// <summary>
    /// 根据时间范围获取日志列表
    /// </summary>
    public async Task<PageResult<GsOperationLog>> GetLogsByTimeRangeAsync(DateTime startTime, DateTime endTime, int page = 1, int pageSize = 20)
    {
        var queryable = _tb
            .Where(l => l.OperationTime >= startTime && l.OperationTime <= endTime)
            .OrderByDescending(l => l.OperationTime);

        var totalCount = await queryable.CountAsync();

        var items = await queryable
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return new PageResult<GsOperationLog>
        {
            Items = items,
            TotalCount = totalCount,
            PageIndex = page,
            PageSize = pageSize
        };
    }

    /// <summary>
    /// 获取最近的日志列表
    /// </summary>
    public async Task<PageResult<GsOperationLog>> GetRecentLogsAsync(int page = 1, int pageSize = 20)
    {
        var queryable = _tb
            .OrderByDescending(l => l.OperationTime);

        var totalCount = await queryable.CountAsync();

        var items = await queryable
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return new PageResult<GsOperationLog>
        {
            Items = items,
            TotalCount = totalCount,
            PageIndex = page,
            PageSize = pageSize
        };
    }

    /// <summary>
    /// 根据条件查询日志
    /// </summary>
    public async Task<PageResult<GsOperationLog>> GetLogsByConditionAsync(OperationLogQueryDto query)
    {
        var queryable = _tb.AsQueryable();

        // 应用查询条件
        if (query.OperatorId.HasValue)
        {
            queryable = queryable.Where(l => l.OperatorId == query.OperatorId.Value);
        }

        if (!string.IsNullOrEmpty(query.OperatorName))
        {
            queryable = queryable.Where(l => l.OperatorName.Contains(query.OperatorName));
        }

        if (!string.IsNullOrEmpty(query.OperationType))
        {
            queryable = queryable.Where(l => l.OperationType == query.OperationType);
        }

        if (!string.IsNullOrEmpty(query.Module))
        {
            queryable = queryable.Where(l => l.Module == query.Module);
        }

        if (!string.IsNullOrEmpty(query.Result))
        {
            queryable = queryable.Where(l => l.Result == query.Result);
        }

        if (query.StartTime.HasValue)
        {
            queryable = queryable.Where(l => l.OperationTime >= query.StartTime.Value);
        }

        if (query.EndTime.HasValue)
        {
            queryable = queryable.Where(l => l.OperationTime <= query.EndTime.Value);
        }

        if (!string.IsNullOrEmpty(query.IpAddress))
        {
            queryable = queryable.Where(l => l.IpAddress.Contains(query.IpAddress));
        }

        // 按操作时间倒序排列
        queryable = queryable.OrderByDescending(l => l.OperationTime);

        var totalCount = await queryable.CountAsync();

        var items = await queryable
            .Skip((query.Page - 1) * query.PageSize)
            .Take(query.PageSize)
            .ToListAsync();

        return new PageResult<GsOperationLog>
        {
            Items = items,
            TotalCount = totalCount,
            PageIndex = query.Page,
            PageSize = query.PageSize
        };
    }

    /// <summary>
    /// 导出日志
    /// </summary>
    public async Task<List<GsOperationLog>> ExportLogsAsync(OperationLogQueryDto query)
    {
        var queryable = _tb.AsQueryable();

        // 应用查询条件（与GetLogsByConditionAsync相同的逻辑）
        if (query.OperatorId.HasValue)
        {
            queryable = queryable.Where(l => l.OperatorId == query.OperatorId.Value);
        }

        if (!string.IsNullOrEmpty(query.OperatorName))
        {
            queryable = queryable.Where(l => l.OperatorName.Contains(query.OperatorName));
        }

        if (!string.IsNullOrEmpty(query.OperationType))
        {
            queryable = queryable.Where(l => l.OperationType == query.OperationType);
        }

        if (!string.IsNullOrEmpty(query.Module))
        {
            queryable = queryable.Where(l => l.Module == query.Module);
        }

        if (!string.IsNullOrEmpty(query.Result))
        {
            queryable = queryable.Where(l => l.Result == query.Result);
        }

        if (query.StartTime.HasValue)
        {
            queryable = queryable.Where(l => l.OperationTime >= query.StartTime.Value);
        }

        if (query.EndTime.HasValue)
        {
            queryable = queryable.Where(l => l.OperationTime <= query.EndTime.Value);
        }

        if (!string.IsNullOrEmpty(query.IpAddress))
        {
            queryable = queryable.Where(l => l.IpAddress.Contains(query.IpAddress));
        }

        // 按操作时间倒序排列，导出所有匹配的记录
        return await queryable
            .OrderByDescending(l => l.OperationTime)
            .ToListAsync();
    }

    /// <summary>
    /// 清理过期日志（只读保护，实际不删除，只标记）
    /// </summary>
    public async Task<int> CleanupExpiredLogsAsync(DateTime beforeDate)
    {
        // 注意：这里不实际删除日志，只标记为已清理，保持审计完整性
        var expiredLogs = await _tb
            .Where(l => l.OperationTime < beforeDate && !l.IsDeleted)
            .ToListAsync();

        foreach (var log in expiredLogs)
        {
            log.IsDeleted = true;
            log.UpdatedAt = DateTime.UtcNow;
            log.Remarks = "系统自动清理";
        }

        await _db.SaveChangesAsync();
        return expiredLogs.Count;
    }

    /// <summary>
    /// 获取日志统计信息
    /// </summary>
    public async Task<object> GetLogStatisticsAsync(DateTime? startDate = null, DateTime? endDate = null)
    {
        var queryable = _tb.AsQueryable();

        if (startDate.HasValue)
        {
            queryable = queryable.Where(l => l.OperationTime >= startDate.Value);
        }

        if (endDate.HasValue)
        {
            queryable = queryable.Where(l => l.OperationTime <= endDate.Value);
        }

        var totalLogs = await queryable.CountAsync();
        var successLogs = await queryable.CountAsync(l => l.Result == "success");
        var errorLogs = await queryable.CountAsync(l => l.Result == "error");

        var topOperators = await queryable
            .GroupBy(l => new { l.OperatorId, l.OperatorName })
            .Select(g => new { g.Key.OperatorName, Count = g.Count() })
            .OrderByDescending(x => x.Count)
            .Take(10)
            .ToListAsync();

        var topModules = await queryable
            .GroupBy(l => l.Module)
            .Select(g => new { Module = g.Key, Count = g.Count() })
            .OrderByDescending(x => x.Count)
            .Take(10)
            .ToListAsync();

        return new
        {
            TotalLogs = totalLogs,
            SuccessLogs = successLogs,
            ErrorLogs = errorLogs,
            SuccessRate = totalLogs > 0 ? (double)successLogs / totalLogs * 100 : 0,
            TopOperators = topOperators,
            TopModules = topModules
        };
    }

    /// <summary>
    /// 获取总日志数
    /// </summary>
    public async Task<int> GetTotalLogsCountAsync()
    {
        return await _tb.CountAsync();
    }

    /// <summary>
    /// 获取过期日志数量
    /// </summary>
    public async Task<int> GetExpiredLogsCountAsync(DateTime beforeDate)
    {
        return await _tb.Where(l => l.OperationTime < beforeDate && !l.IsDeleted).CountAsync();
    }
} 